package com.bjsxt.controller;

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bjsxt.domain.Coin;
import com.bjsxt.dto.CoinDto;
import com.bjsxt.feign.CoinFeignClient;
import com.bjsxt.model.Result;
import com.bjsxt.service.CoinService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * description:
 * 数字货币控制器
 * TODO: 这里在进行权限配置的时候可能没有对应的权限，以后后期需要统一进行添加
 *
 * @author ALIENWARE
 * @version v1.0.0
 * @create 1/2/2024
 **/
@RestController
@RequestMapping("/coins")
@Api(tags = "数字货币控制器")
public class CoinController implements CoinFeignClient {

    /**
     * 数字货币业务层接口
     */
    @Autowired
    private CoinService coinService;

    /**
     * 分页查询数字货币
     *
     * @param page   分页对象<Coin>
     * @param name   币种名称
     * @param type   币种类型，xnb：人民币,default：比特币系列,ETH：以太坊,ethToken：以太坊代币,
     * @param status 状态，status=1：启用,0：禁用
     * @param title  币种标题
     * @param wallet 钱包类型，rgb：认购币,qbb：钱包币
     * @return 统一响应对象
     */
    @GetMapping
    @PreAuthorize("hasAuthority('trade_coin_type_query')")
    @ApiOperation(value = "条件分页查询数字货币", authorizations = {@Authorization("Authorization")})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页", dataType = "Long", paramType = "query", example = "1"),
            @ApiImplicitParam(name = "size", value = "每页条数", dataType = "Long", paramType = "query", example = "20"),
            @ApiImplicitParam(name = "name", value = "币种名称", dataType = "String", paramType = "query", example = "测试货币"),
            @ApiImplicitParam(name = "type", value = "币种类型，xnb：人民币,default：比特币系列,ETH：以太坊,ethToken：以太坊代币", dataType = "String", paramType = "query", example = "xnb"),
            @ApiImplicitParam(name = "status", value = "状态，status=1：启用,0：禁用", dataType = "Byte", paramType = "query", example = "1"),
            @ApiImplicitParam(name = "title", value = "币种标题", dataType = "Long", paramType = "String", example = "测试使用的数字货币"),
            @ApiImplicitParam(name = "wallet_type", value = "钱包类型，rgb：认购币,qbb：钱包币", dataType = "String", paramType = "query", example = "qbb"),
    })
    public Result<Page<Coin>> findByPage(@ApiIgnore Page<Coin> page, String name, String type, Byte status, String title, @RequestParam(value = "wallet_type", required = false) String wallet) {
        // 增加查询条件的排序规则
        page.addOrder(OrderItem.desc(Coin.COL_LAST_UPDATE_TIME));
        // 调用业务层进行数据的查询
        Page<Coin> coinPage = coinService.pageByNameAndTypeAndStatusAndTitleAndWalletType(page, name, type, status, title, wallet);
        // 返回响应数据
        return Result.success(coinPage);
    }

    /**
     * 根据状态获取全部的币种
     *
     * @param status 状态：0: 无效 1:有效
     * @return 统一响应对象
     */
    @GetMapping("/all")
    // @PreAuthorize("hasAuthority('trade_coin_type_query')")
    @ApiOperation(value = "根据状态获取全部的币种", authorizations = {@Authorization("Authorization")})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "status", value = "状态：0-无效；1-有效；", dataType = "Byte", required = true, paramType = "query", example = "0")
    })
    public Result<List<Coin>> getAll(@NotNull Byte status) {
        // 调用业务层查询所有的币种
        List<Coin> coins = coinService.listByStatus(status);
        // 返回响应数据
        return Result.success(coins);
    }

    /**
     * 根据币种 ID 获取币种数据
     *
     * @param id 币种 ID
     * @return 统一响应对象
     */
    @GetMapping("/info/{id}")
    @PreAuthorize("hasAuthority('trade_coin_type_query')")
    @ApiOperation(value = "根据 ID 获取币种数据", authorizations = {@Authorization("Authorization")})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "币种数据 ID", dataType = "Long", required = true, paramType = "query", example = "1")
    })
    public Result<Coin> getById(@PathVariable @NotNull Long id) {
        // 调用业务层进行数据的查询
        Coin coin = coinService.getById(id);
        // 返回响应数据
        return Result.success(coin);
    }

    /**
     * 根据 ID 集合查询币种数据
     *
     * @param ids id 集合
     * @return 返回的币种信息集合
     */
    @Override
    public List<CoinDto> getByIds(List<Long> ids) {
        // 调用业务层进行数据的查询
        return coinService.getByIds(ids);
    }

    /**
     * 增加一个币种数据
     *
     * @param coin 币种修改数据对象
     * @return 统一响应对象
     */
    @PostMapping
    @PreAuthorize("hasAuthority('trade_coin_type_create')")
    @ApiOperation(value = "增加一个币种数据", authorizations = {@Authorization("Authorization")})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "coin", value = "Coin 的 json 数据", dataType = "String", paramType = "body", example = "{}")
    })
    public Result<Coin> add(@Validated @RequestBody Coin coin) {
        // 调用业务层方法进行数据的保存
        boolean flag = coinService.save(coin);
        // 如果为 true 新增成功，这里返回的时候需要返回 Coin 对象，因为前端需要这个对象的 coinId，但是为什么这个对象有 ID，因为 mybatis-plus 对数据进行了回填，查询的方式
        if (flag) return Result.success(coin);
        // 如果为 false 新增失败
        return Result.fail("新增失败");
    }

    /**
     * 修改一个币种数据
     *
     * @param coin 币种修改数据对象
     * @return 统一响应对象
     */
    @PatchMapping
    @PreAuthorize("hasAuthority('trade_coin_type_update')")
    @ApiOperation(value = "修改一个币种数据", authorizations = {@Authorization("Authorization")})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "coin", value = "Coin 的 json 数据", dataType = "String", paramType = "body", example = "{}")
    })
    public Result<Void> update(@Validated @RequestBody Coin coin) {
        // 调用业务层方法进行数据的更新
        boolean flag = coinService.updateById(coin);
        // 如果为 true 更新成功
        if (flag) return Result.success("修改成功");
        // 如果为 false 更新失败
        return Result.fail("修改失败");
    }

    /**
     * 启用/禁用一个货币
     *
     * @param id     "要启用/禁用货币的 Id
     * @param status 要设置的货币的状态值 1: 启用 0: 禁用
     * @return 统一响应对象
     */
    @PostMapping("/setStatus")
    @PreAuthorize("hasAuthority('trade_coin_type_update')")
    @ApiOperation(value = "启用/禁用一个货币", authorizations = {@Authorization("Authorization")})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "要启用/禁用货币的 Id", dataType = "Long", required = true, paramType = "query", example = "1"),
            @ApiImplicitParam(name = "status", value = "要设置的货币的状态值 1: 启用 0: 禁用", dataType = "Byte", paramType = "query", example = "0")
    })
    public Result<Void> updateStatus(@NotNull Long id, Byte status) {
        // 创建更新的 coinType 对象
        Coin coinType = new Coin();
        // 设置 id 及需要更新的值
        coinType.setId(id);
        coinType.setStatus(status);
        // 调用业务层方法进行数据的更新
        boolean flag = coinService.updateById(coinType);
        // 如果为 true 更新成功
        if (flag) return Result.success("更新成功");
        // 如果为 false 更新失败
        return Result.fail("更新失败");
    }
}
